/* Scheduler include files. */
#include "FreeRTOS.h"
#include "task.h"
#include "projdefs.h"
#include "timers.h"

/* include files. */
#include "vtUtilities.h"
#include "LCDtask.h"
#include "myTimers.h"
#include "uart.h"
#include "motorControl.h"
/* **************************************************************** */
// WARNING: Do not print in this file -- the stack is not large enough for this task
/* **************************************************************** */

/* *********************************************************** */
// Functions for the LCD Task related timer
//
// how often the timer that sends messages to the LCD task should run
// Set the task up to run every 100 ms
#define lcdWRITE_RATE_BASE	( ( portTickType ) 100 / portTICK_RATE_MS)

#define UART_TEST_RATE		( ( portTickType )  75/ portTICK_RATE_MS)

static uint8_t uart_req_flag = 0;

// Callback function that is called by the LCDTimer
//   Sends a message to the queue that is read by the LCD Task
void LCDTimerCallback(xTimerHandle pxTimer)
{
	if (pxTimer == NULL) {
		VT_HANDLE_FATAL_ERROR(0);
	} else {
		// When setting up this timer, I put the pointer to the 
		//   LCD structure as the "timer ID" so that I could access
		//   that structure here -- which I need to do to get the 
		//   address of the message queue to send to 
		vtLCDStruct *ptr = (vtLCDStruct *) pvTimerGetTimerID(pxTimer);
		// Make this non-blocking *but* be aware that if the queue is full, this routine
		// will not care, so if you care, you need to check something
		if (SendLCDTimerMsg(ptr,lcdWRITE_RATE_BASE,0) == errQUEUE_FULL) {
			// Here is where you would do something if you wanted to handle the queue being full
			VT_HANDLE_FATAL_ERROR(0);
		}
	}
}

void startTimerForLCD(vtLCDStruct *vtLCDdata) {
	if (sizeof(long) != sizeof(vtLCDStruct *)) {
		VT_HANDLE_FATAL_ERROR(0);
	}
	xTimerHandle LCDTimerHandle = xTimerCreate((const signed char *)"LCD Timer",lcdWRITE_RATE_BASE,pdTRUE,(void *) vtLCDdata,LCDTimerCallback);
	if (LCDTimerHandle == NULL) {
		VT_HANDLE_FATAL_ERROR(0);
	} else {
		if (xTimerStart(LCDTimerHandle,0) != pdPASS) {
			VT_HANDLE_FATAL_ERROR(0);
		}
	}
}


/* *********************************************************** */
// Functions for the Temperature Task related timer
//
// how often the timer that sends messages to the LCD task should run
// Set the task up to run every 500 ms
#define adcWRITE_RATE_BASE	( ( portTickType ) 100 / portTICK_RATE_MS)

// Callback function that is called by the AdcTimer
//   Sends a message to the queue that is read by the Adc Task
void AdcTimerCallback(xTimerHandle pxTimer)
{  
	/*if (pxTimer == NULL) {
		VT_HANDLE_FATAL_ERROR(0);
	} else {
		// When setting up this timer, I put the pointer to the 
		//   Temperature structure as the "timer ID" so that I could access
		//   that structure here -- which I need to do to get the 
		//   address of the message queue to send to 
		vtAdcStruct *ptr = (vtAdcStruct *) pvTimerGetTimerID(pxTimer);
		// Make this non-blocking *but* be aware that if the queue is full, this routine
		// will not care, so if you care, you need to check something
		if (SendAdcTimerMsg(ptr,adcWRITE_RATE_BASE,0) == errQUEUE_FULL) {
			// Here is where you would do something if you wanted to handle the queue being full
			VT_HANDLE_FATAL_ERROR(0);
		}
	}  	 */
}


void UARTTimerCallback(xTimerHandle pxTimer)
{

	
	if(uart_req_flag == 0)
	{	
		reqSensorData();
		uart_req_flag = 1;	
	}
	else
	{
		reqEncoderData();
		uart_req_flag = 0;
	}
	

}


void startTimerForAdc(vtAdcStruct* vtAdcdata) {
	if (sizeof(long) != sizeof(vtAdcStruct *)) {
		VT_HANDLE_FATAL_ERROR(0);
	}
	xTimerHandle AdcTimerHandle = xTimerCreate((const signed char *)"Adc Timer",lcdWRITE_RATE_BASE,pdTRUE,(void *) vtAdcdata,AdcTimerCallback);
	if (AdcTimerHandle == NULL) {
		VT_HANDLE_FATAL_ERROR(0);
	} else {
		if (xTimerStart(AdcTimerHandle,0) != pdPASS) {
			VT_HANDLE_FATAL_ERROR(0);
		}
	}
}


void startUARTTestTimer(UARTStruct* uart)
{
	xTimerHandle UARTTimerHandle = xTimerCreate((const signed char *)"UART Timer",UART_TEST_RATE,pdTRUE,(void *) uart,UARTTimerCallback);
	if (UARTTimerHandle == NULL) {
		VT_HANDLE_FATAL_ERROR(0);
	} else {
		if (xTimerStart(UARTTimerHandle,0) != pdPASS) {
			VT_HANDLE_FATAL_ERROR(0);
		}
	}
}										 

/*------------------------------------------------------------------------*/

#define driveWRITE_RATE_BASE	( ( portTickType ) 2000 / portTICK_RATE_MS)


void DriveTimerCallback(xTimerHandle pxTimer)
{
	if (pxTimer == NULL) {
		VT_HANDLE_FATAL_ERROR(0);
	} else {
		// When setting up this timer, I put the pointer to the 
		//   Temperature structure as the "timer ID" so that I could access
		//   that structure here -- which I need to do to get the 
		//   address of the message queue to send to 
		int i = 0;
		uint8_t valueArray[5];
		uint8_t value;
		value = 1;
		for(i=0;i<sizeof(valueArray);i++)
		{
  			valueArray[i] = i; // Initializing each element seperately
		}
		vtDriveStruct *ptr = (vtDriveStruct *) pvTimerGetTimerID(pxTimer);
		//vtTempStruct *ptr = (vtTempStruct *) pvTimerGetTimerID(pxTimer);
		// Make this non-blocking *but* be aware that if the queue is full, this routine
		// will not care, so if you care, you need to check something
	
	/*	if (SendDriveValueMsg(ptr,0 ,1, 2, 3, 0) == errQUEUE_FULL) {
			// Here is where you would do something if you wanted to handle the queue being full
			VT_HANDLE_FATAL_ERROR(0);
		}
	*/
	
		/*if (SendDriveValueMsg(ptr, tempWRITE_RATE_BASE, 0) == errQUEUE_FULL) {
			printf("count is out\n");
			VT_HANDLE_FATAL_ERROR(0);
		}
		*/
	}
}

void startTimerForDrive(vtDriveStruct *vtDriveData) {
/*
	if (sizeof(long) != sizeof(vtDriveStruct *)) {
		VT_HANDLE_FATAL_ERROR(0);
	}
	xTimerHandle DriveTimerHandle = xTimerCreate((const signed char *)"Drive Timer",driveWRITE_RATE_BASE,pdTRUE,(void *) vtDriveData,DriveTimerCallback);
	if (DriveTimerHandle == NULL) {
		VT_HANDLE_FATAL_ERROR(0);
	} else {
		if (xTimerStart(DriveTimerHandle,0) != pdPASS) {
			VT_HANDLE_FATAL_ERROR(0);
		}
	}
	*/
}